package com.taplinker.client.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import android.annotation.TargetApi;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class RecordingManager{
	public static final int TIME_LONGEST = 60 * 1000;
	public static final int TIME_SHORTEST = 1000;
	private static final String TAG = "RecordingManager";
	
	private MediaRecorder mRecorder;
	private File mRecAudioFile;
    
	private MediaPlayer mPlayer;
	
	private static RecordingManager instance;
	
	private RecordingManager() {
	}
	
	public static RecordingManager getInstance() {
		if (instance!=null) {
			return instance;
		}
		synchronized(RecordingManager.class) {
			if (instance == null) {
				instance = new RecordingManager();
			}
		}
		return instance;
	}
	
	
	@TargetApi(Build.VERSION_CODES.CUPCAKE)
	public void recording(Context ctx) {
		File file = new File(LocalFileManager.getInstance().getVoiceDir());
		if (!file.exists()) {
			file.mkdirs();
		}
		mRecAudioFile = new File(file, UUID.randomUUID().toString() + ".amr");
		
		mRecorder = new MediaRecorder();
		// 设置麦克风
		mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
		// 输出文件格式
		mRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
		// 音频文件编码
		mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
		mRecorder.setMaxDuration(60*1000);
		// 输出文件路径
		mRecorder.setOutputFile(mRecAudioFile.getAbsolutePath());
		Log.e(TAG + "mRecorder.setOutputFile:", mRecAudioFile.getAbsolutePath());
		// 准备--开始
		try {
			mRecorder.prepare();
			mRecorder.start();
		} catch (IllegalStateException e) {
			e.printStackTrace();
			mRecorder.release();
		} catch (IOException e) {
			e.printStackTrace();
			mRecorder.release();
		}
	}

	public synchronized String stopRec(Context ctx) {
		try {
			if (mRecorder == null) {
				return null;
			} else {
				mRecorder.stop();
			}
			File file = new File(mRecAudioFile.getAbsolutePath());
			if (file == null || !file.exists()) {
				return null;
			}
			int seconds = MediaPlayer.create(ctx, Uri.fromFile(file)).getDuration();
			if(seconds < RecordingManager.TIME_SHORTEST) {
				file.delete();
				return null;
			}
			return file.getAbsolutePath();
		} catch(Exception ex){
			 Log.e(TAG, ex.getMessage(), ex.getCause());
		} finally {
			if (mRecorder != null) {
				mRecorder.release();
				mRecorder = null;
			}
		}
		return null;
	}
	
	public void playRec(String path, int mTime, final CallBack callBack){
		if (mPlayer!=null && mPlayer.isPlaying()) {
			mPlayer.stop();
			mPlayer.release();
		} 
		mPlayer = new MediaPlayer();
		FileInputStream fis = null;
		try {
			File file = new File(path); 
		    fis = new FileInputStream(file);
		    mPlayer.reset();
		    mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			mPlayer.setDataSource(fis.getFD());
			mPlayer.setVolume(1f, 1f);
			Log.d(TAG, "playRec:" + path);
			mPlayer.prepare();
			mPlayer.start();
			
			if(callBack != null) {
				Handler handler = new InnerHandler(){
					@Override
					public void handleMessage(Message msg) {
						super.handleMessage(msg);
						callBack.doAfterOver();
					}
				};
				final Message m = handler.obtainMessage();
				new Timer().schedule(new TimerTask() {
					
					@Override
					public void run() {
						m.sendToTarget();
					}
				}, mTime);
			}
			
		} catch (IOException e) {
			if (fis!=null) {
				try {
					fis.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}
	}
	
	public boolean isPlaying() {
		return mPlayer == null ? false : mPlayer.isPlaying();
	}

	public void releaseResource() {
		if (mPlayer!=null && mPlayer.isPlaying()) {
			mPlayer.stop();
			mPlayer.release();
		} 
		
		if(mRecorder!=null) {
			mRecorder.release();
			mRecorder = null;
		}
	}
	
	public interface CallBack {
		void doAfterOver();
	}
	
	static class InnerHandler extends Handler {
		
	}
}
